#include <REGX52.H>
#include "DELAY.H"
#include "TIMER0.H"

// 蜂鸣器端口定义
sbit buzzer = P2 ^ 5;

// 音乐数据数组指针
unsigned char p;
// 高位数据
unsigned char high;
// 低位数据
unsigned char low;
// 4分音符倍数
unsigned char multiple = 4;

// 小星星
// unsigned char code music[] = {
//     239, 205, 125, // 1, c
//     239, 205, 125, // 1, c
//     245, 48, 125,  // 5, g
//     245, 48, 125,  // 5, g
//     246, 94, 125,  // 6, a
//     246, 94, 125,  // 6, a
//     245, 48, 250,  // 5, g, 2音符
//     243, 221, 125, // 4, f
//     243, 221, 125, // 4, f
//     243, 36, 125,  // 3, e
//     243, 36, 125,  // 3, e
//     241, 145, 125, // 2, d
//     241, 145, 125, // 2, d
//     239, 205, 250, // 1, c, 2音符
//     245, 48, 125,  // 5, g
//     245, 48, 125,  // 5, g
//     243, 221, 125, // 4, f
//     243, 221, 125, // 4, f
//     243, 36, 125,  // 3, e
//     243, 36, 125,  // 3, e
//     241, 145, 250, // 2, d, 2音符
//     245, 48, 125,  // 5, g
//     245, 48, 125,  // 5, g
//     243, 221, 125, // 4, f
//     243, 221, 125, // 4, f
//     243, 36, 125,  // 3, e
//     243, 36, 125,  // 3, e
//     241, 145, 250, // 2, d, 2音符
//     0xFF           // 停止标志位
// };

// 生日快乐
unsigned char code music[] = {
    240, 181, 125, // 5, c#, 降8度, 降半音
    240, 181, 125, // 5, c#, 降8度, 降半音
    243, 36, 125,  // 6, e, 降8度
    241, 145, 125, // 5, d, 降8度
    245, 48, 125,  // 1, g
    244, 139, 250, // 7, f#, 2音符, 降8度
    240, 181, 125, // 5, c#, 降8度, 降半音
    240, 181, 125, // 5, c#, 降8度, 降半音
    243, 36, 125,  // 6, e, 降8度
    241, 145, 125, // 5, d, 降8度
    246, 94, 125,  // 2, a
    245, 48, 250,  // 1, g, 2音符
    240, 181, 125, // 5, c#, 降8度, 降半音
    240, 181, 125, // 5, c#, 降8度, 降半音
    248, 201, 125, // 5, d1
    247, 107, 125, // 3, b
    245, 48, 125,  // 1, g
    244, 139, 125, // 7, f#, 降8度
    243, 36, 125,  // 6, e, 降8度
    247, 107, 125, // 4, b, 降半音
    247, 107, 125, // 4, b, 降半音
    247, 107, 125, // 3, b
    245, 48, 125,  // 1, g
    246, 94, 125,  // 2, a
    245, 48, 250,  // 1, g, 2音符
    0xFF           // 停止标志位
};

void main()
{
  Timer0Init();
  while (1)
  {
    // 不是停止标志位
    if (music[p] != 0xFF)
    {
      high = music[p++];
      low = music[p++];
      // 音符时值
      delayMs(multiple * music[p++]);
      TR0 = 0;
      // 音符间短暂停顿
      delayMs(5);
      TR0 = 1;
    }
    else
    {
      TR0 = 0;
      // 延迟1秒后重新播放
      delayMs(1000);
      p = 0;
    }
  }
}

void Timer0_Routine() interrupt 1
{
  // 不是休止符
  if (high)
  {
    TL0 = low;
    TH0 = high;
    // 翻转蜂鸣器IO口
    buzzer = !buzzer;
  }
}
